home *** CD-ROM | disk | FTP | other *** search
- #include <assert.h>
-
- // These pragmas must be defined so that templates may be expanded.
- //
- #pragma defmacro MACRO "macro" delimiter=} recursive
- #pragma defmacro template "template" delimiter=}
- #pragma defmacro DECLARE "declare" delimiter=> recursive lines
- #pragma defmacro IMPLEMENT "implement" delimiter=> recursive lines
-
- #ifndef NULL
- # if sizeof (long) == sizeof (void *)
- # define NULL 0L
- # else
- # define NULL 0
- # endif
- #endif
-
- //------------------------------------------------------------------------
- // Your basic ring buffer.
- //
- enum FifoStatus {Empty, HasData, Overflow};
-
- template<class T> class Fifo<T> {
- T *buffer;
- unsigned size;
- unsigned head;
- unsigned tail;
- unsigned overflow;
- unsigned advance (unsigned i) { return (i+1) % size; }
- public:
- Fifo<T> (unsigned sz);
- ~Fifo<T> ();
- FifoStatus status ();
- FifoStatus get (T &e);
- void put (T &e);
- };
-
-
- template<class T> Fifo<T>::Fifo<T> (unsigned sz) {
- tail = overflow = 0;
- head = tail + 1;
- buffer = (T *)new T[size = sz];
- assert (buffer != NULL);
- }
-
-
- template<class T> Fifo<T>::~Fifo<T> () { delete buffer; }
-
-
- template<class T> FifoStatus Fifo<T>::status () {
- if (overflow) {
- overflow = 0;
- return Overflow;
- }
- if (advance (tail) == head)
- return Empty;
- return HasData;
- }
-
-
- template<class T> FifoStatus Fifo<T>::get (T &e) {
- unsigned t_indx = advance (tail);
- if (t_indx == head)
- return Empty;
- e = buffer[tail = t_indx];
- return HasData;
- }
-
- template<class T> void Fifo<T>::put (T &e) {
- if (head == tail)
- overflow++;
- else {
- buffer[head] = e;
- head = advance (head);
- }
- }
-
- DECLARE Fifo<int>;
- IMPLEMENT Fifo<int>;
-
- Fifo<int> myfifo (32);
-
-
-
- // Here is some stuff pulled directly from the ARM and converted for cpp's
- // syntax.
- //
-
- class Complex {
- float re, im;
- public:
- Complex ();
- // ...
- };
-
- template<class T> class Vector<T> {
- T* v;
- int sz;
- public:
- Vector<T> (int);
- T& elem (int i) { return v[i]; }
- T& operator[] (int i);
- //...
- };
-
- DECLARE Vector<void *>;
-
- template<class T> class Pvector<T>: Vector<void *> {
- public:
- Pvector<T> (int i): (i) {}
- T*& elem (int i)
- { return (T*&) Vector<void *>::elem (i); }
- T*& operator[] (int i)
- { return (T*&) Vector<void *>::operator[] (i); }
- // ....
- };
-
- DECLARE Pvector<int *>;
- DECLARE Pvector<Complex *>;
- DECLARE Pvector<char *>;
-
-
- // Using templates to build ``type'' shells around a general purpose class.
- // A redo of Stroustrup's slist class from _The C++ Programming Language_
- //
-
- // The general purpose class. Specific purpose classes will be derived from
- // this one.
- //
- class Slist;
-
- class Slink { friend class Slist; // friend class Slist_iterator;
- Slink *next;
- void *e;
- Slink (void *a, Slink *p): e(a), next(p) {}
- };
-
- class Slist { // friend class Slist_iterator;
- Slink *tail;
- # define head tail->next
- public:
- Slist (): tail(NULL) {}
- Slist (void *a) {
- tail = (Slink *)new Slink (a, NULL);
- assert (tail != NULL);
- head = tail;
- }
- ~Slist () { clear (); }
- int insert (void *a);
- int append (void *a);
- void *get ();
- void clear ();
- };
-
-
- // Now for the template class.
- //
- template<class T> class GSlist<T>: Slist {
- public:
- GSlist<T> () {}
- GSlist<T> (T *a): Slist ((void *)a) {}
- ~GSlist<T> () { clear (); }
- int insert (T *a) { return Slist::insert ((void *)a); }
- int append (T *a) { return Slist::append ((void *)a); }
- T *get () { return (T *)Slist::get (); }
- };
-
- struct Employee {
- char *name;
- char *socSec;
- int payScale;
- // ...
- };
-
- struct Card {
- int rank;
- int suit;
- };
-
- // Declarations.
- //
- DECLARE GSlist<Employee>;
- DECLARE GSlist<Card>;
-
- // Definitions.
- //
- GSlist<Employee> employeeList;
- GSlist<Card> cardList;
-